package com.tbit.uqbike.webmanager.business.maintain_performance.controller;

import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.uqbike.webmanager.business.maintain_performance.constant.PerformanceBizType;
import com.tbit.uqbike.webmanager.business.maintain_performance.constant.PerformanceExportField;
import com.tbit.uqbike.webmanager.business.maintain_performance.object.dto.config.MovePerformanceConfig;
import com.tbit.uqbike.webmanager.business.maintain_performance.object.dto.stat.*;
import com.tbit.uqbike.webmanager.business.maintain_performance.service.MovePerformanceService;
import com.tbit.uqbike.webmanager.business.maintain_performance.service.PerformanceRuleGroupService;
import com.tbit.uqbike.webmanager.controller.BaseController;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.Excel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 挪车绩效配置
 *
 * @author <a href="mailto:zheng.zebiao@tbit.com.cn">zb</a>
 * @since 2025/2/21
 */
@Slf4j
@RestController
@RequestMapping("/movePerformance")
@RequiredArgsConstructor
public class MovePerformanceController {
    final PerformanceRuleGroupService ruleGroupService;
    final MovePerformanceService performanceService;

    /**
     * 获取挪车绩效配置
     *
     * @param accountId 区域id
     */
    @GetMapping("/getConfig")
    public Result<MovePerformanceConfig> getPerformanceConfig(Integer accountId) {
        MovePerformanceConfig result = ruleGroupService.selectBizPerformanceConfig(accountId,
                MovePerformanceConfig::fromRaw,
                PerformanceBizType.MOVE
        );
        result.initDefaultIfNull();
        return Result.success(result);
    }

    /**
     * 更新挪车绩效配置
     *
     * @param config 挪车绩效配置
     */
    @PostMapping("/updateConfig")
    @OperateLog(module = ModuleEnum.PERFORMANCE, methods = MethodEnum.PERFORMANCE_MOVE_CONFIG_UPDATE)
    public Result<Void> updatePerformanceConfig(@RequestBody MovePerformanceConfig config) {
        // TODO 参数校验 干不完了，先搁置
        ruleGroupService.saveRaw(config.getAccountId(), config.toRaw());
        return Result.success();
    }

    /**
     * 分页查询挪车绩效详情
     *
     * @param req 请求参数
     */
    @PostMapping("/queryDetailPage")
    public Result<PageResult<MovePerformanceDetail>> queryPerformanceDetail(@Valid @RequestBody MovePerformanceDetailReq req) {
        return Result.success(performanceService.queryDetailPage(req));
    }

    /**
     * 导出挪车绩效详情
     *
     * @param req 请求参数
     * @return 文件路径
     */
    @PostMapping("/exportDetail")
    public JsonResult exportDetail(@Valid @RequestBody MovePerformanceDetailReq req) {
        req.setPageNo(1);
        req.setPageSize(Integer.MAX_VALUE);
        PageResult<MovePerformanceDetail> page = performanceService.queryDetailPage(req);
        List<MovePerformanceDetail> list = page.getList();

        // 动态导出字段
        long mask = -1;
        if (req.getExportFields() != null) {
            mask = 0;
            for (String field : req.getExportFields()) {
                mask |= PerformanceExportField.Move.getFieldBit(field);
            }
        }

        ExcelUtil<MovePerformanceDetail> excel = new ExcelUtil<>(MovePerformanceDetail.class, mask);
        return excel.exportExcel(list, "挪车绩效详情");
    }

    /**
     * 更新挪车绩效
     *
     * @param performanceId 挪车绩效id
     * @param performance   更新后的绩效值
     * @param remark        备注
     */
    @PutMapping("/updatePerformance")
    @OperateLog(module = ModuleEnum.PERFORMANCE, methods = MethodEnum.PERFORMANCE_MOVE_UPDATE)
    public Result<Void> updatePerformance(@RequestParam Long performanceId,
                                          @RequestParam BigDecimal performance,
                                          @RequestParam String remark) {
        performanceService.updatePerformance(performanceId, performance, remark);
        return Result.success();
    }

    /**
     * 查询挪车绩效统计图表数据
     *
     * @param accountId     区域id
     * @param startTime     开始日期
     * @param endTime       结束日期
     * @param accountUserId 运维人员id
     * @param machineType   车辆类型 0-电单车 1-自行车
     * @param isValid       审核状态 0-无效 1-有效
     */
    @GetMapping("/queryStatChart")
    public Result<List<PerformanceChartPerDateDetail>> queryStatChart(
            @RequestParam Integer accountId,
            @RequestParam Date startTime,
            @RequestParam Date endTime,
            Integer accountUserId,
            @RequestParam(defaultValue = "0") Integer machineType,
            Integer isValid,
            HttpServletRequest request
    ) {
        LoginInfo loginInfo = BaseController.getLogin(request);
        return Result.success(performanceService.queryStatChart(accountId, startTime, endTime, accountUserId, machineType, isValid, loginInfo));
    }

    /**
     * 分页查询挪车绩效概览数据
     *
     * @param req 请求参数
     */
    @PostMapping("/queryOverviewPage")
    public Result<PageResult<PerformanceOverviewResp>> queryOverviewPage(@Valid @RequestBody PerformanceOverviewReq req) {
        return Result.success(performanceService.queryOverviewPage(req));
    }

    @PostMapping("/exportOverview")
    public JsonResult exportOverview(@Valid @RequestBody PerformanceOverviewReq req) {
        req.setPageNo(1);
        req.setPageSize(Integer.MAX_VALUE);
        PageResult<PerformanceOverviewResp> page = performanceService.queryOverviewPage(req);


        // 生成Excel
        String fileName = "挪车绩效总览记录";
        String title = "挪车绩效总览";
        int row = 1;
        List<String> cellNameList = new ArrayList<>();
        cellNameList.add("运维姓名");
        cellNameList.add("运维手机号");
        cellNameList.add("总次数");
        cellNameList.add("有效");
        cellNameList.add("无效");
        cellNameList.add("绩效");
        HSSFWorkbook excel = Excel.createExcel(title, cellNameList);
        for (PerformanceOverviewResp overview : page.getList()) {
            List<String> excelData = new ArrayList<>();
            excelData.add(Optional.ofNullable(overview.getAccountUserName()).orElse(""));
            excelData.add(Optional.ofNullable(overview.getAccountUserPhone()).orElse(""));
            excelData.add(overview.getTotal().toString());
            excelData.add(overview.getValid() + "");
            excelData.add(overview.getInvalid() + "");
            excelData.add(overview.getPerformanceSum().toString());
            Excel.createExcelData(excel, excelData, row);
            row++;
        }

        // 导出文件
        String filename = ExcelUtil.encodingFilename(fileName);
        try (OutputStream out = Files.newOutputStream(Paths.get(ExcelUtil.getAbsoluteFile(filename)))) {
            excel.write(out);
            excel.close();
            return JsonResult.ok(filename);
        } catch (Exception e) {
            log.error("[挪车绩效] 导出总览时发生错误", e);
            throw new BaseException("导出Excel失败");
        }
    }
}
